#include "myshell.h"
#include <iostream>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <string>
using namespace std;

#define _SIZE 64
char* gargv[_SIZE];//命令行参数表
int gargc;

char pwd[1024];
int lastcode;

string GetUser()
{
	char* user = getenv("USER");
	if (user == NULL) return "None";
	return user;
}
string GetHostName()
{
        char hostname[256];
	int ret=gethostname(hostname,sizeof(hostname));
	if(ret != 0) return "None";
	return hostname;
}

string GetPwd()
{
	//让命令行标识符显示的路径实时变化
	char temp[1024];
	getcwd(temp, sizeof(temp));
	//更新环境变量表中PWD
	snprintf(pwd, sizeof(pwd), "PWD=%s", temp);
	putenv(pwd);
	
	string cwd = temp;
	int pos =cwd.rfind("/");
	if (pos == string::npos) return "None";
	cwd = cwd.substr(pos + 1);
	//特殊情况：当前的路径就是"/"
	return cwd.empty() ? "/" : cwd;
}

string GetHomePath()
{
	char* homepath = getenv("HOME");
	if (homepath == NULL) return "None";
	return homepath;
}

void PrintCommondString()
{
	string user = GetUser();
	string hostname = GetHostName();
	string pwd = GetPwd();

	printf("%s@%s:%s# ", user.c_str(), hostname.c_str(), pwd.c_str());
}

bool GetCommondString(char cmd_str_buff[], int len)
{
	if (cmd_str_buff == NULL || len <= 0) return false;
	char* ret = fgets(cmd_str_buff, len, stdin);
	if (ret == NULL) return false;
	//处理数组的最后一个字符：回车键(\n)
	cmd_str_buff[strlen(cmd_str_buff) - 1] = '\0';
	//针对特殊情况：只输入一个回车键
	return strlen(cmd_str_buff) == 0 ? false : true;
}

bool ParseCommondString(char cmd[])
{
	if (cmd == NULL) return false;
	//利用strtok函数来截取cmd字符串
	gargv[gargc++] = strtok(cmd, " ");
	//将剩下的内容依次截取下来放入到gargv数组中
	while((bool)(gargv[gargc++] = strtok(NULL, " ")));
	//处理一下gargc，因为当上面的while循环结束，因为最后一个值是NULLstrtok函数才返回，但是会导致gargc多加一次
	gargc--;
//#define DEBUG
#ifdef DEBUG
	printf("gargc: %d\n", gargc);
	for (int i = 0; i < gargc; i++)
	{
		printf("gargv[%d]: %s\n", i, gargv[i]);
	}
#endif // DEBUG

	return true;
}

void Init()
{
	gargc = 0;
	memset(gargv, 0, sizeof(gargv));
}

void ForkAndExec()
{
	pid_t id = fork();
	if (id < 0)
	{
		perror("fork fail!");
	}
	else if (id == 0)
	{
		//子进程来执行命令
		execvp(gargv[0],gargv);
		exit(0);
	}
	else
	{
		//父进程
		int status=0;
		pid_t rid = waitpid(id, &status, 0);
		if (rid > 0)
		{
			//等待成功
			lastcode=WEXITSTATUS(status);
		}
	}
}

bool HandleBuiltCommond()
{
	string cmd = gargv[0];
	bool ret = false;
	//处理内建命令
	if (cmd == "cd")
	{
		if (gargc == 2)
		{
			//说明是指定进入某个路径或者是cd ~等操作
			string target = gargv[1];
			if (target == "~")
			{
				chdir(GetHomePath().c_str());
			}
			else
			{
				chdir(gargv[1]);
			}
		}
		else if (gargc == 1)
		{
			chdir(GetHomePath().c_str());
		}

		ret = true;
	}
	else if (cmd == "echo")
	{
		if (gargc == 2)
		{
			string args = gargv[1];
			if (args[0] == '$')
			{
				if (args[1] == '?')
				{
					printf("lastcode: %d\n", lastcode);
				}
				else
				{
					//打印系统变量
					char* arr = &args[1];
					printf("%s\n", getenv(arr));
				}
			}
			else
			{
				printf("%s\n", args.c_str());
			}
		}

		ret = true;
		lastcode = 0;
	}

	return ret;
}
